// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	9/19/2014 2:44:39 PM				
// -----------------------------

#include "Scene.h"

#include "Application.h"
#include "RenderManager.h"
#include "Camera.h"
#include "FreeCamera.h"
#include "Timer.h"

#include <iomanip>

Scene::Scene(const TString& lpName)
	: m_Name(lpName)
{
	m_lpCamera = new FreeCamera(_T("DefaultCamera"));
}

Scene::~Scene()
{
	for (Actor* lpActor : m_Actors)
		delete lpActor;

	delete m_lpCamera;
}

void Scene::OnActivate(Application* lpApp)
{

}
void Scene::OnDeactivate(Application* lpApp)
{

}
void Scene::OnGUI(Application* lpApp, IRenderTarget2D* lpTarget)
{
}

void Scene::Load(Application* lpApp)
{
}
void Scene::Update(Application* lpApp, Float deltaTime)
{
	m_lpCamera->Update(lpApp, deltaTime);

	for (Actor* lpActor : m_Actors)
	{
		if (lpActor->m_bEnabled)
			lpActor->Update(lpApp, deltaTime);
	}
}

void Scene::AddActor(Actor* lpActor)
{
	m_Actors.push_back(lpActor);
	lpActor->m_lpScene = this;
}
void Scene::RemoveActor(Actor* lpActor, Bool bDelete)
{
	auto foundIt = std::find(m_Actors.begin(), m_Actors.end(), lpActor);
	if (foundIt != m_Actors.end())
		m_Actors.erase(foundIt);
	lpActor->m_lpScene = nullptr;

	if (bDelete)
		delete lpActor;
}

void Scene::SetCamera(Camera* lpCamera, Bool bRemoveFromScene, Bool bDelete)
{
	Camera* lpOld = m_lpCamera;
	m_lpCamera = lpCamera;

	if (bRemoveFromScene && ContainsActor(lpOld))
		RemoveActor(lpOld, bDelete);
	if (!bRemoveFromScene && bDelete)
		delete lpOld;
}

const TString& Scene::GetName() const
{
	return m_Name;
}
Camera* Scene::GetCamera() const
{
	return m_lpCamera;
}

Actor* Scene::FindActor(const TString& Name) const
{
	auto foundIt = std::find_if(m_Actors.begin(), m_Actors.end(), [&Name](Actor* lpActor)
	{
		if (lpActor->GetName() == Name)
			return true;
		return false;
	});
	if (foundIt != m_Actors.end())
		return (*foundIt);
	return nullptr;
}
Bool Scene::ContainsActor(Actor* lpActor) const
{
	auto foundIt = std::find(m_Actors.begin(), m_Actors.end(), lpActor);
	if (foundIt != m_Actors.end())
		return true;
	return false;
}
vector<Actor*> Scene::GetActorsWithFlags(UInt32 uFlags) const
{
	vector<Actor*> actors;
	for (Actor* lpActor : m_Actors)
	{
		if (lpActor->m_bEnabled && lpActor->HasFlags(uFlags))
			actors.push_back(lpActor);
	}
	if (m_lpCamera->HasFlags(uFlags))
		actors.push_back(m_lpCamera);
	return actors;
}